<?php

declare(strict_types=1);
/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
namespace assist;

/**
 * Class Age
 * @package assist
 */
class Age{

    /**
     * 计算年龄精准到年月日
     * @param  int $birthday
     * @return array
     */
    public static function calAge(int $birthday):array
    {

        list($byear, $bmonth, $bday)    = explode('-',date('Y-m-d',$birthday) );
        list($year, $month, $day)       = explode('-',date('Y-m-d'));

        $bmonth = intval($bmonth);
        $bday   = intval($bday);

        if ($bmonth < 10) {
            $bmonth = '0' . $bmonth;
        }

        if ($bday < 10) {
            $bday = '0' . $bday;
        }

        $bi = intval($byear . $bmonth . $bday);
        $ni = intval($year . $month . $day);

        $not_birth = 0;
        if ($bi > $ni) {

            $not_birth  = 1;
            $tmp        = [$byear, $bmonth, $bday];

            list($byear, $bmonth, $bday)= [$year, $month, $day];
            list($year, $month, $day)   = $tmp;
            list($bi, $ni)              = [$ni, $bi];
        }

        $years = 0;
        while (($bi + 10000) <= $ni) {
            $bi += 10000;
            $years++;
            $byear++;
        }

        list($m, $d) = self::getMD([$year, $month, $day], [$byear, $bmonth, $bday]);

        return [
            'year'      => $years,
            'month'     => $m,
            'day'       => $d,
            'notBirth' => $not_birth
        ];
    }


    /**
     * 只能用于一年内计算
     *
     * @param array $ymd
     * @param array $bymd
     * @return array
     */
    private static function getMD(array $ymd,array $bymd)
    {

        list($y, $m, $d)    = $ymd;
        list($by, $bm, $bd) = $bymd;
        $by=(int)$by;

        if (($m . $d) < ($bm . $bd)) {
            $m +=12;
        }

        $month = 0;

        $bmbd=$bm . $bd;
        while (((int)$bmbd + 100) <= ($m . $d)) {
            $bm++;
            $month++;
        }

        if ($bd <= $d) {
            $day = $d - $bd;
        } else {
            $mdays = $bm > 12 ? self::_getMothDay( ++$by, (int)$bm - 12) : self::_getMothDay($by,(int) $bm);
            $day = $mdays - $bd + $d;
        }
        return array($month, $day);
    }

    /**
     * @param $year
     * @param $month
     * @return int
     */
    private static function _getMothDay(int $year, int $month):int
    {
        switch ($month) {
            case 1:
            case 3:
            case 5:
            case 7:
            case 8:
            case 10:
            case 12:
                $day = 31;
                break;
            case 2:
                $day = (intval($year % 4) ? 28 : 29); //能被4除尽的为29天其他28天
                break;
            default:
                $day = 30;
                break;
        }
        return $day;
    }

}